package cn.xd.security.config;

import cn.xd.security.filter.AuthenticationFilter;
import cn.xd.security.provider.AdminUserCaptchaProvider;
import cn.xd.security.provider.CustomerUserWxMiniAppProvider;
import jakarta.annotation.Resource;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

// 使用@EnableWebSecurity注解开启Spring Security功能
@Configuration
@EnableWebSecurity
@EnableGlobalAuthentication
@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityConfig {
    @Resource
    private AdminUserCaptchaProvider adminUserCaptchaProvider;
    @Resource
    private CustomerUserWxMiniAppProvider customerUserWxMiniAppProvider;
    @Resource
    private AuthenticationFilter authenticationFilter;
    @Resource
    private BaseUrlAuthorizationManager baseUrlAuthorizationManager;
    @Resource
    private MainExceptionHandlingConfigurer mainExceptionHandlingConfigurer;

    // 定义一个SecurityFilterChain bean，用于配置安全过滤器链
    @Bean
    public SecurityFilterChain securityFilterChain(SecurityProperties securityProperties, HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .csrf(AbstractHttpConfigurer::disable)
                .cors(Customizer.withDefaults())
                .formLogin(AbstractHttpConfigurer::disable)
                .logout(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorize ->
                        authorize.requestMatchers(securityProperties.getPublicUrl().toArray(String[]::new)).permitAll()
                                .requestMatchers(securityProperties.getNotAccessUrl().toArray(String[]::new)).authenticated()
                                // 除了上面那些请求都需要认证
                                .anyRequest().access(baseUrlAuthorizationManager)

                )
                .addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling(mainExceptionHandlingConfigurer)
                .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
//                .formLogin(Customizer.withDefaults())
                .httpBasic(AbstractHttpConfigurer::disable);
        return httpSecurity.build();
    }

    @Bean
    public AuthenticationEventPublisher authenticationEventPublisher
            (ApplicationEventPublisher applicationEventPublisher) {
        return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationEventPublisher applicationEventPublisher) {
        ProviderManager providerManager = new ProviderManager(adminUserCaptchaProvider, customerUserWxMiniAppProvider);
        providerManager.setAuthenticationEventPublisher(applicationEventPublisher);
        return providerManager;
    }


//    /**
//     * Spring Security 自定义安全配置
//     */
//    @Bean
//    public WebSecurityCustomizer webSecurityCustomizer() {
//        return (web) ->
//                // 不走过滤器链(场景：静态资源js、css、html)
//                web.ignoring().requestMatchers(
//                        "/webjars/**",
//                        "/doc.html",
//                        "/swagger-resources/**",
//                        "/v3/api-docs/**",
//                        "/swagger-ui/**"
//                );
//    }
}
